from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from tb_menu.models import *
from django.db.models import Q
from django.conf import settings
# from django.views.decorators.csrf import csrf_exempt
# from django.contrib import auth
# from django.utils.functional import SimpleLazyObject
# from django.contrib.auth.models import AbstractUser
from rest_framework import status as status_code
# Create your views here.


def response_origin(data):
    response = Response(data)
    response['Access-Control-Allow-Origin'] = '*'
    return response


@api_view(http_method_names=['POST','GET'])
def menu(request):
    if request.method == "POST":
        try:
            menu_data = request.data

            projectID = menu_data["projectID"]
            projectName = menu_data['projectName']
            menu_json = menu_data["menu_json"]
            if TbMenu.objects.all().exists():
                s = TbMenu()
                s.project_id = projectID
                s.project_name = projectName
                s.menujson = menu_json
                s.version = 1
                s.enabled = 0
                s.save()
            else:
                s = TbMenu()
                s.project_id = projectID
                s.project_name = projectName
                s.menujson = menu_json
                s.version = 1
                s.enabled = 1
                s.save()
            return response_origin({"status":status_code.HTTP_201_CREATED})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message":str(e)})
    elif request.method == "GET":
        try:
            dicts = TbMenu.objects.all()
            # print(dicts)
            list1 = []
            for j in dicts:
                menuJson = j.menujson
                version_num = j.version
                last_version = ""
                next_version = ""
                lls = TbMenu.objects.filter(version=int(version_num)-1)
                nv = TbMenu.objects.filter(version=int(version_num) + 1)
                if lls.exists():
                    last_version = lls.values("id")[0]['id']
                if nv.exists():
                    next_version = nv.values("id")[0]['id']

                dict2 = {"menu_id":j.id,"project_id":j.project_id,"project_name":j.project_name,
                         "version":j.version,"enabled":j.enabled,"menu_json":eval(menuJson.replace("null", "None")),"last_version_id":last_version,
                         "next_version_id":next_version,"create_time":j.create_time.strftime(settings.REST_FRAMEWORK["DATETIME_FORMAT"])
                         }
                list1.append(dict2)
            #     print(list1)
            # return response_origin(list1)
            return response_origin({"status": "True","data":list1})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_404_NOT_FOUND, "message": str(e)})


@api_view(http_method_names=['POST','PUT','GET'])
def menu2(request,menuID):
    if request.method == "POST":
        try:
            menu_data = request.data
            projectID = menu_data["projectID"]
            projectName = menu_data['projectName']
            menu_json = menu_data["menu_json"]
            # num = TbMenu.objects.filter(id=int(menuID)).values("version")[0]["version"]
            num = TbMenu.objects.all().count()
            other = TbMenu()
            other.project_id = projectID
            other.project_name = projectName
            other.menujson = menu_json
            other.version = num+1
            other.enabled = 0
            other.save()
            return response_origin({"status": status_code.HTTP_201_CREATED})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message":str(e)})
    elif request.method == "PUT":
        try:
            menu_data = request.data
            status = menu_data["status"]
            menu_json = menu_data["menu_json"]
            if status == "enabled":
                TbMenu.objects.all().update(enabled=0)
                TbMenu.objects.filter(id=menuID).update(enabled=1,menujson=menu_json)
                TbMymenu.objects.all().update(timeout="True")
                return response_origin({"status": status_code.HTTP_202_ACCEPTED})
            else:
                if TbMenu.objects.filter(id=menuID,enabled=1).exists():
                    TbMenu.objects.filter(id=menuID).update(menujson=menu_json)
                    TbMymenu.objects.all().update(timeout="True")
                else:
                    TbMenu.objects.filter(id=menuID).update(menujson=menu_json)
                return response_origin({"status": status_code.HTTP_202_ACCEPTED})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_406_NOT_ACCEPTABLE, "message": str(e)})
    elif request.method == "GET":
        try:
            sysdata = TbMenu.objects.filter(id=menuID)
            list1 = []
            last_version = ""
            next_version = ""
            for i in sysdata:
                version_num = i.version
                lls = TbMenu.objects.filter(version=int(version_num)-1)
                nv = TbMenu.objects.filter(version=int(version_num) + 1)
                if lls.exists():
                    last_version = lls.values("id")[0]['id']
                if nv.exists():
                    next_version = nv.values("id")[0]['id']
                dict1 = {"project_id":i.project_id,"project_name":i.project_name,"menu_json":i.menujson,
                         "version":version_num,"menu_id":i.id,"last_version_id":last_version,
                         "create_time":i.create_time.strftime(settings.REST_FRAMEWORK["DATETIME_FORMAT"]),
                         "next_version_id":next_version,"enabled":i.enabled}
                list1.append(dict1)
            return response_origin({"status":status_code.HTTP_200_OK,"data":list1})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_400_BAD_REQUEST,"message": str(e)})


@api_view(http_method_names=['POST','PUT','GET'])
def mymenu(request,userID):
    if request.method == "POST":
        try:
            menu_data = request.data
            mymenujson = menu_data["my_menu_json"]
            vip = TbMymenu()
            vip.user_id = int(userID)
            vip.my_menu_json = mymenujson
            vip.timeout = "True"
            vip.save()
            return response_origin({"status":status_code.HTTP_201_CREATED})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message": str(e)})
    elif request.method == "PUT":
        try:
            menu_data = request.data
            mymenujson = menu_data["my_menu_json"]
            TbMymenu.objects.filter(user_id=userID).update(my_menu_json=mymenujson)
            return response_origin({"status":status_code.HTTP_202_ACCEPTED})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_406_NOT_ACCEPTABLE, "message": str(e)})
    elif request.method == "GET":
        try:
            dict1 = TbMymenu.objects.filter(user_id=userID)
            dicts = {}
            for menuD in dict1:
                dicts = {"my_menu_json":menuD.my_menu_json,"create_time":menuD.create_time.strftime(settings.REST_FRAMEWORK["DATETIME_FORMAT"])}
            return response_origin({"status":status_code.HTTP_200_OK,"data":dicts})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_404_NOT_FOUND, "message": str(e)})


@api_view(http_method_names=['PUT','GET'])
def my_system_menu(request,userID):
    if request.method == "GET":
        try:
            # if request.user.id:
            #     userID = request.user.id
            # else:
                # menu_data = request.data
                # userID = menu_data['user_id']
            if TbMymenu.objects.filter(user_id=userID).exists():
                t = TbMymenu.objects.filter(user_id=userID).values("timeout")[0]['timeout']
                if t == "True":
                    uname = TbUserRoleMap.objects.filter(user_id=userID)
                    if not uname.exists():
                        return response_origin({"status": status_code.HTTP_200_OK, "data": []})
                    list2 = [m.role_id for m in uname]
                    list3 = [TbRoleFunctionMap.objects.filter(role_id=n,function__is_active=1,function__desc="primary").values('function_id')
                             for n in list2]
                    menuJson = TbMenu.objects.filter(enabled=1).values("menujson")[0]["menujson"]
                    menu_json = eval(menuJson.replace("null", "None"))
                    list5 = []
                    for functionID in list3:
                        for funs in functionID:
                            list5.append(funs["function_id"])
                    list6 = []
                    for all_menu in menu_json:
                        if 'content' in all_menu.keys() and all_menu['content'] != []:
                            d = all_menu['content']
                            for da in d:
                                daa = da["list"]
                                # print(daa)
                                for daaa in daa:
                                    # print(daaa)
                                    if 'id' not in daaa.keys() or int(daaa["id"]) not in list5:
                                            list6.append(daaa)
                                    else:
                                        pass
                                for j in list6:
                                    daa.remove(j)
                                list6 = []
                        else:
                            pass
                    TbMymenu.objects.filter(user_id=userID).update(system_menu_json=menu_json,timeout="False")
                    return response_origin({"status":status_code.HTTP_200_OK,"data":menu_json})
                else:
                    # list1 = []
                    dicts = {}
                    system_menu = TbMymenu.objects.filter(user_id=userID)
                    for i in system_menu:
                        dicts = eval(i.system_menu_json)
                        # list1.append(dicts)
                    return response_origin({"status": status_code.HTTP_200_OK,"data":dicts})
            else:
                # username = "F1330319"
                # print('ccc')
                uname = TbUserRoleMap.objects.filter(user_id=userID)
                # print(uname)
                if not uname.exists():
                    return response_origin({"status":status_code.HTTP_200_OK,"data":[]})
                list2 = [m.role_id for m in uname]
                list3 = [TbRoleFunctionMap.objects.filter(role_id=n,function__is_active=1,function__desc="primary").values('function_id')
                         for n in list2]
                menuJson = TbMenu.objects.filter(enabled=1).values("menujson")[0]["menujson"]
                menu_json = eval(menuJson.replace("null", "None"))
                list5 = []
                for functionID in list3:
                    for funs in functionID:
                        list5.append(funs["function_id"])
                list6 = []
                for all_menu in menu_json:
                    if 'content' in all_menu.keys() and all_menu['content'] != []:
                        d = all_menu['content']
                        for da in d:
                            daa = da["list"]
                            # print(daa)
                            for daaa in daa:
                                # print(daaa)
                                if 'id' not in daaa.keys() or int(daaa["id"]) not in list5:
                                    list6.append(daaa)
                                else:
                                    pass
                            for j in list6:
                                daa.remove(j)
                            list6 = []
                    else:
                        pass
                s = TbMymenu()
                s.user_id = int(userID)
                s.system_menu_json = menu_json
                s.timeout = "False"
                s.my_menu_json = []
                s.save()
                return response_origin({"status": status_code.HTTP_200_OK, "data": menu_json})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_404_NOT_FOUND, "message": str(e)})
    elif request.method == "PUT":
        try:
            menu_data = request.data
            time_status = menu_data["timeout"]
            # user_id = menu_data["user_id"]
            if time_status == "True":
                TbMymenu.objects.filter(user_id=userID).update(timeout=time_status)
                return response_origin({"status":status_code.HTTP_201_CREATED})
            else:
                return response_origin({"status": status_code.HTTP_400_BAD_REQUEST})
        except Exception as e:
            return response_origin({"status": status_code.HTTP_406_NOT_ACCEPTABLE, "message": str(e)})


@api_view(http_method_names=['GET'])
def user_func(request,userID):
    if request.method == "GET":
        try:
            uname = TbUserRoleMap.objects.filter(user_id=userID)

            if not uname.exists():
                return response_origin({"status": status_code.HTTP_200_OK, "data": []})
            list2 = [m.role_id for m in uname]
            # print(list2)
            list3 = [TbRoleFunctionMap.objects.filter(role_id=n,function__is_active=1,function__desc="primary").values("function_id")
                     for n in list2]
            list5 = []
            for functionID in list3:
                for funs in functionID:
                    list5.append(funs["function_id"])
            list4 = []
            # print(list5)
            list6 = list(set(list5))
            # print(list6)
            for function in list6:
                ddd = TbFunction.objects.filter(id=function).values("id","code","name","parent_id","parent_code","full_code","desc","create_date","is_active","definer_id","project_id")
                list4.append(ddd[0])
            return response_origin({"status":status_code.HTTP_200_OK,"data":list4})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message":str(e)})


@api_view(http_method_names=['GET'])
def user_auth(request,userID):
    if request.method == "GET":
        try:
            uname = TbUserRoleMap.objects.filter(user_id=userID)
            if not uname.exists():
                return response_origin({"status": status_code.HTTP_200_OK, "data": []})
            list2 = [m.role_id for m in uname]
            # print(list2)
            # print(TbRoleFunctionMap.objects.filter(Q(role_id=49274,function__is_active=1,function__desc="modal")))
            list3 = [TbRoleFunctionMap.objects.filter(
                    Q(role_id=n, function__is_active=1, function__desc="modal") | Q(role_id=n, function__is_active=1,
                      function__desc="secondary")) for n in list2]
            # list5 = []
            # dict2 = {}
            dict3 = {}
            # print(list3)
            for functionID in list3:
                for funs in functionID:
                    dicts = {funs.function.full_code:"true"}
                    dict3 = dict(dicts, **dict3)
            return response_origin({"status":status_code.HTTP_200_OK,"data":dict3})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message":str(e)})


@api_view(http_method_names=['GET'])
def system_func(request):
    if request.method == "GET":
        try:
            funcs = TbFunction.objects.filter(desc="primary",is_active=1).values("id")
            list5 = [funcs_id["id"] for funcs_id in funcs]
            # print(list5)
            menuJson = TbMenu.objects.filter(enabled=1).values("menujson")[0]["menujson"]
            menu_json = eval(menuJson.replace("null", "None"))
            list6 = []
            list8 = []
            for all_menu in menu_json:
                if 'content' in all_menu.keys() and all_menu['content'] != []:
                    d = all_menu['content']
                    for da in d:
                        daa = da["list"]
                        for daaa in daa:
                            if 'id' not in daaa.keys():
                                continue
                            if int(daaa["id"]) in list5:
                                list6.append(daaa["id"])
                            else:
                                pass
                else:
                    pass

            list7 = list(set(list5).difference(set(list6)))
            if not list7:
                for func_id in list5:
                    dict2 = TbFunction.objects.filter(id=func_id)
                    for fun_data in dict2:
                        dict4 = {"function_id": fun_data.id, "code": fun_data.code, "parent_code": fun_data.parent_code,
                                 "full_code": fun_data.full_code, "desc": fun_data.desc,
                                 "is_active": fun_data.is_active,
                                 "create_date": fun_data.create_date, "project_id": fun_data.project_id,
                                 "definer_id": fun_data.definer_id, "selected": "true", "name": fun_data.name}
                        list8.append(dict4)
                return response_origin({"status": status_code.HTTP_200_OK, "data":list8})
            else:
                for fun in list5:
                    if fun in list7:
                        dict1 = TbFunction.objects.filter(id=fun)
                        for fun_data in dict1:
                            dict3 = {"function_id":fun_data.id,"code":fun_data.code,"parent_code":fun_data.parent_code,
                                     "full_code":fun_data.full_code,"desc":fun_data.desc,"is_active":fun_data.is_active,
                                     "create_date":fun_data.create_date.strftime(settings.REST_FRAMEWORK["DATETIME_FORMAT"]),
                                     "project_id":fun_data.project_id,"definer_id":fun_data.definer_id,
                                     "selected":"false","name":fun_data.name}
                            list8.append(dict3)
                    else:
                        dict2 = TbFunction.objects.filter(id=fun)
                        for fun_data in dict2:
                            dict4 = {"function_id": fun_data.id, "code": fun_data.code, "parent_code": fun_data.parent_code,
                                     "full_code": fun_data.full_code, "desc": fun_data.desc,
                                     "is_active": fun_data.is_active,
                                     "create_date": fun_data.create_date, "project_id": fun_data.project_id,
                                     "definer_id": fun_data.definer_id,"selected":"true","name":fun_data.name}
                            list8.append(dict4)
                return response_origin({"status": status_code.HTTP_200_OK, "data":list8})
        except Exception as e:
            return response_origin({"status":status_code.HTTP_406_NOT_ACCEPTABLE,"message":str(e)})
